﻿////////////////////////////////////////////////////////////////////////////////////////////
// File: PSpring.cs                                                                       //
// Author: Mike Binnix                                                                    //
// Desc: force generator to simulate a simple spring connecting two particles together.   //
////////////////////////////////////////////////////////////////////////////////////////////

using System;
using Microsoft.Xna.Framework;

namespace SlothEngine.Physics.Forces
{
    class PSpring : IPForceGenerator
    {
        #region Attributes
        protected XNAParticle otherParticle;
        protected float springConstant;
        protected float restLength;
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the particle at the other end of the spring.
        /// </summary>
        public XNAParticle OtherParticle
        {
            get
            {
                return otherParticle;
            }
            set
            {
                otherParticle = value;
            }
        }
        /// <summary>
        /// Gets or sets the spring constant.
        /// </summary>
        public float SpringConstant
        {
            get
            {
                return springConstant;
            }
            set
            {
                springConstant = value;
            }
        }
        /// <summary>
        /// Gets or sets the rest length of the spring
        /// </summary>
        public float RestLength
        {
            get
            {
                return restLength;
            }
            set
            {
                restLength = value;
            }
        }
        #endregion

        #region Constructors
        public PSpring(XNAParticle otherParticle, float springConstant, float restLength)
        {
            this.otherParticle = otherParticle;
            this.springConstant = springConstant;
            this.restLength = restLength;
        }
        #endregion

        #region Methods
        /// <summary>
        /// Applies the spring force to the object.
        /// </summary>
        /// <param name="gameTime">Time since last update.</param>
        /// <param name="particle">particle to change.</param>
        public virtual void Update(GameTime gameTime, XNAParticle particle)
        {
            // Find vector of spring.
            Vector2 force = particle.Position;
            force -= otherParticle.Position;

            // Find magnitude of force
            float magnitude = (float)Math.Sqrt(force.X * force.X + force.Y * force.Y);
            magnitude = Math.Abs(magnitude - restLength);
            magnitude *= springConstant;

            // Find final force
            force.Normalize();
            force *= -magnitude;

            particle.AddForce(force);
        }
        #endregion
    }
}
